﻿using BlockMain_Class;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Newtonsoft.Json;
using System.Threading;

namespace InsertServers
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {

        public static ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("127.0.0.1:6379");
        private TextBox tb;
        //委托 线程委托修改ui
        public delegate void UpdateTextCallback(string message);
        public static MongodbHelpers<AccountBook> mon = new MongodbHelpers<AccountBook>();
        public MainWindow()
        {
            InitializeComponent();
            this.tb = text;
            WindowStartupLocation = WindowStartupLocation.CenterScreen;
            this.Topmost = true;
        }

        /// <summary>
        /// 监听入链  只处理主备份链
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //开启监听
            ISubscriber sub = redis.GetSubscriber();
            //1)处理peer队列
            sub.Subscribe("copy", (channel, message) =>
            {
                //输出收到的消息
                AddTest($"[{DateTime.Now:HH:mm:ss}] {message}");
                var data = message;
                //节点raft处理一致性
                Copy(data);
            });
            //提示
            MessageBox.Show("已开始监听");
            this.start.Content = "正在监听...";
            this.start.IsEnabled = false;
        }

        private object obj = new object();

        /// <summary>
        /// 操作入列
        /// </summary>
        public void Copy(string data)
        {
            lock (obj)
            {
                var jsondata = Cache.Get(data);
                Record r = JsonConvert.DeserializeObject<Record>(jsondata.ToString());
                Add(r);
            }
        }


        /// <summary>
        /// 添加
        /// </summary>
        public void Add(Record r)
        {
            //获取最后一条数据
            var last = mon.QueryAll().ToList().LastOrDefault();
            if (last != null)
            {

                BlockMain_Class.Block oldBlock = new BlockMain_Class.Block
                {
                    Index = last.Height,
                    TimeStamp = last.TimeStamp,
                    Data = last.Data,
                    Hash = last.Hash,
                    PrevHash = last.PrevHash,
                };

                //生成新的 
                BlockMain_Class.Block newBlock = BlockGenerator.GenerateBlock(oldBlock, r.JsonData, r.AddTime);

                //验证区块的有效性
                if (BlockGenerator.IsBlockValid(newBlock, oldBlock))
                {
                    //追加缓存

                    //追加当前区块到链中
                    AccountBook b = new AccountBook();
                    b.Height = newBlock.Index;
                    b.TimeStamp = newBlock.TimeStamp;
                    b.Data = r.JsonData;
                    b.Hash = newBlock.Hash;
                    b.PrevHash = newBlock.PrevHash;
                    var result = mon.Insert(b);
                }

            }
            else
            {
                AccountBook b = new AccountBook();
                //没有最后一条追加创世链
                b.Height = 0;
                b.TimeStamp = "1525716699872";
                b.Data = "欢迎你光临我的联盟链..";
                b.Hash = "";
                b.PrevHash = "";
                var result = mon.Insert(b);
                Add(r);
                Thread.Sleep(1000);
            }

        }


        /// <summary>
        /// 修改文本框内容
        /// </summary>
        /// <param name="message"></param>
        private void UpdateText(string message)
        {
            tb.AppendText(message + "\n");
            tb.ScrollToEnd();//滚动到光标处
        }

        //工作线程
        private void AddTest(string text)
        {
            //调用委托
            tb.Dispatcher.Invoke(
                new UpdateTextCallback(this.UpdateText), text
            );
        }
    }
}
